using BackOffice.Application.Services;
using BackOffice.Application.DTOs;
using System.Text;

namespace Backoffice.Api.Middleware;

public class LoggingMiddleware
{
    private readonly RequestDelegate _next;

    public LoggingMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var startTime = DateTime.UtcNow;
        var originalBodyStream = context.Response.Body;

        try
        {
            // 记录请求开始
            await LogRequest(context, "API请求开始");

            // 继续处理请求
            await _next(context);

            // 记录请求完成
            var duration = DateTime.UtcNow - startTime;
            await LogRequest(context, $"API请求完成 - 耗时: {duration.TotalMilliseconds}ms", duration.TotalMilliseconds);
        }
        catch (Exception ex)
        {
            // 记录错误
            await LogRequest(context, $"API请求错误: {ex.Message}", null, "ERROR");
            throw;
        }
    }

    private async Task LogRequest(HttpContext context, string action, double? duration = null, string level = "INFO")
    {
        try
        {
            // 从作用域中获取ILogService
            var logService = context.RequestServices.GetService<ILogService>();
            if (logService == null)
            {
                Console.WriteLine("无法获取ILogService");
                return;
            }

            var username = context.User?.Identity?.Name ?? "anonymous";
            var ipAddress = GetClientIpAddress(context);
            var userAgent = context.Request.Headers["User-Agent"].ToString();
            var method = context.Request.Method;
            var path = context.Request.Path;
            var statusCode = context.Response.StatusCode;

            var description = $"{method} {path} - 状态码: {statusCode}";
            if (duration.HasValue)
            {
                description += $" - 耗时: {duration.Value:F2}ms";
            }

            var logDto = new LogRecordDto(
                Username: username,
                Action: $"[{level}] {action}",
                Description: description,
                IpAddress: ipAddress,
                UserAgent: userAgent
            );

            await logService.RecordLogAsync(logDto);
        }
        catch (Exception ex)
        {
            // 避免日志记录失败影响主流程
            Console.WriteLine($"日志记录失败: {ex.Message}");
        }
    }

    private string GetClientIpAddress(HttpContext context)
    {
        var ip = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
        if (string.IsNullOrEmpty(ip))
        {
            ip = context.Request.Headers["X-Real-IP"].FirstOrDefault();
        }
        if (string.IsNullOrEmpty(ip))
        {
            ip = context.Connection.RemoteIpAddress?.ToString();
        }
        return ip ?? "unknown";
    }
}

public static class LoggingMiddlewareExtensions
{
    public static IApplicationBuilder UseLogging(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<LoggingMiddleware>();
    }
}